<template>
    <a-form :model="form" ref="formRef" :rules="formRules" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }">
        <a-form-item :label="$t('upperComputer.menu.parentMenu')" name="parentCode">
            <a-tree-select allow-clear treeNodeFilterProp="title" show-search v-model:value="form.parentCode"
                :tree-data="treeData" :field-names="{
                    children: 'childrens',
                    label: 'displayName',
                    key: 'id',
                    value: 'code',
                }" />
        </a-form-item>
        <a-form-item :label="$t('upperComputer.menu.menuCode')" name="code">
            <a-input v-model:value="form.code" :maxlength="50" :disabled="form.id ? true : false" />
        </a-form-item>
        <a-form-item :label="$t('upperComputer.menu.menuName')" name="displayName">
            <a-input v-model:value="form.displayName" :maxlength="50" />
        </a-form-item>
        <a-form-item :label="$t('upperComputer.menu.link')" name="link">
            <a-input v-model:value="form.link" :maxlength="200" />
        </a-form-item>
        <a-form-item :label="$t('upperComputer.menu.sort')" name="sort">
            <a-input-number v-model:value="form.sort" :min="1" :precision="0" style="width: 100%" />
        </a-form-item>
        <a-form-item :label="$t('upperComputer.menu.icon')" name="icon">
            <a-select v-model:value="form.icon" allow-clear show-search>
                <a-select-option v-for="(item, index) in iconNames" :key="index" :value="item">
                    {{ item }}&nbsp;
                    <menu-icon :iconName="item" />
                </a-select-option>
            </a-select>
        </a-form-item>
        <a-form-item :label="$t('upperComputer.menu.isActive')" name="isActive">
            <a-switch v-model:checked="form.isActive" />
        </a-form-item>
        <a-form-item :label="$t('upperComputer.menu.description')" name="description">
            <a-textarea v-model:value="form.description" autoSize :maxlength="255" showCount />
        </a-form-item>
    </a-form>
</template>

<script setup lang='ts'>
import i18n from '@/i18n';
import MenuIcon from '@/components/icon/index.vue';
import { MenuDto } from '@/models/menu';
import { getMenuApi, getMenusApi, postMenuApi, putMenuApi } from '@/services/menu';
import { message, type FormInstance } from 'ant-design-vue';
import type { Rule } from 'ant-design-vue/lib/form';
import { onMounted, ref, type Ref } from 'vue';
import { IconNames } from '@/components/icon';
import type { TreeSelectProps } from 'ant-design-vue/lib/vc-tree-select/TreeSelect';
import type { BaseOptionType } from 'ant-design-vue/lib/select';

const props = defineProps<{ id: number, code: string }>();
defineExpose({ ok });

const iconNames: Array<string> = IconNames;
const treeData: Ref<BaseOptionType | undefined> = ref<TreeSelectProps['treeData']>();
const form: Ref<MenuDto> = ref<MenuDto>(new MenuDto);
const formRef: Ref<FormInstance | undefined> = ref<FormInstance>();
const formRules: Record<string, Rule[]> = {
    code: [
        { required: true, trigger: 'blur', validator: codeValidator },
    ],
    displayName: [
        {
            required: true,
            max: 50,
            message: i18n.global.t('upperComputer.menu.rules.menuName'),
            trigger: 'blur',
        },
    ],
    sort: [
        {
            required: true,
            type: 'number',
            message: i18n.global.t('upperComputer.menu.rules.sort'),
            trigger: 'blur',
        }
    ]
};

onMounted(() => {
    getTreeData();
    getForm();
});

async function getTreeData(): Promise<void> {
    treeData.value = await getMenusApi(props.code);
}

async function getForm(): Promise<void> {
    if (props.id) {
        form.value = await getMenuApi(props.id);
    }
}

function codeValidator(rule: Rule, value: string, callback: Function): Promise<void> {
    const reg: RegExp = /^[A-Z][a-zA-Z]{1,49}$/;
    if (reg.test(value)) {
        return Promise.resolve();
    }
    return Promise.reject(i18n.global.t('upperComputer.menu.rules.capital'));
}

async function ok(): Promise<boolean> {
    try {
        await formRef.value?.validate();
        if (props.id) {
            await putMenuApi(form.value);
        } else {
            await postMenuApi(form.value);
        }
        message.success(i18n.global.t('common.' + (props.id ? 'editSuccess' : 'addSuccess')));
        return true;
    } catch {
        return false;
    }
}
</script>